using MultiAgentsClient.ChatDataStructures;
using MultiAgentsShared;
using static MultiAgentsClient.Manager.AgentManager;
using static MultiAgentsClient.Manager.UserInfoManager;

namespace MultiAgentsClient.Presentation;

public partial record AgentListModel
{
    private readonly IEventBus eventBus;

    public IListState<AgentDisp> AgentsDisp => ListState<AgentDisp>.Empty(this);

    public record LoadAgentByShareCodeClickCommand();

    public AgentListModel()
    {
        eventBus = EventBus.Instance;

        eventBus.Subscribe<CreateNewAgentCompleteCommand>(async cmd => { await CreateNewAgentCompleteCommandHandler(cmd); });
        eventBus.Subscribe<RemoveAgentCompleteCommand>(async cmd => { await RemoveAgentCompleteCommandHandler(cmd); });


        eventBus.Subscribe<UpdateAgentCompleteCommand>(async cmd => { await UpdateAgentCompleteCommandHandler(cmd); });
        eventBus.Subscribe<FetchUserdataCompletedCommand>(async cmd => { await FetchUserdataCompletedCommandHandler(cmd); });
    }

    public void AddAgent()
    {
        eventBus.Publish(new CreateNewAgentCommand());
    }

    public void AddAgentByShareCode()
    {
        eventBus.Publish(new LoadAgentByShareCodeClickCommand());
    }

    public void RemoveAgent(int agentId)
    {
        eventBus.Publish(new RemoveAgentCommand(agentId));
    }

    public void ShareAgent(int agentId)
    {
        eventBus.Publish(new ShareAgentCommand(agentId));
    }

    public void LoadAgent(int agentId)
    {
        eventBus.Publish(new LoadAgentCommand(agentId));
    }

    #region commands
    private async Task CreateNewAgentCompleteCommandHandler(CreateNewAgentCompleteCommand cmd)
    {
        await AgentsDisp.AddAsync(cmd.AgentDisp);
    }

    private async Task RemoveAgentCompleteCommandHandler(RemoveAgentCompleteCommand cmd)
    {
        await AgentsDisp.RemoveAllAsync(item => item.Id == cmd.Agent, default);
    }

    private async Task UpdateAgentCompleteCommandHandler(UpdateAgentCompleteCommand cmd)
    {
        await AgentsDisp.UpdateAsync(
            match: cp => cp.Id == cmd.AgentConfigDisp.Id,
            updater: cp => cmd.AgentConfigDisp,
            default
        );
    }

    private async Task FetchUserdataCompletedCommandHandler(FetchUserdataCompletedCommand cmd)
    {
        await AgentsDisp.RemoveAllAsync(item => true, default);
        foreach (AgentTemplate agentTemplate in cmd.UserData.customAgents)
        {
            await AgentsDisp.AddAsync(agentTemplate.ToDisp());
        }
    }
    #endregion
}
